// 导入express模块
const express = require('express');
// 创建express服务器实例
const app = express()

// 安装并导入jwt相关的包
const jwt = require('jsonwebtoken');
// 导入用于将客户端发送过来的JWT字符串，解析还原成JSON对象的包
const expressJWT = require('express-jwt')

// 允许跨域资源共享
const cors = require('cors')
app.use(cors())

// 导入解析表单数据的中间件body-parser
const parser = require('body-parser');
// 使用app.use()注册中间件
app.use(parser.urlencoded({ extended: false }))

// 定义secret 密钥，建议将密钥命名为secretKey,本质就是一个字符串
const secretKey = 'wd No1'

// 注册将JWT字符串解析还原成JSON对象的中间件 \/转义
// 注意：只要配置成功express-jwt这个中间件，就可以将解析出来的用户信息，挂载到req.user属性上
app.use(expressJWT({ secret: secretKey, algorithms: ['HS256'] }).unless({ path: [/^\/api\//] }))


// 登录接口
app.post('/api/login', function(req, res) {
    // 将req.body请求体中的数据，转存为userinfo常量
    const userinfo = req.body
        // 登录失败
    if (userinfo.username !== 'admin' || userinfo.password !== '000000') {
        return res.send({
            status: 400,
            message: '登录失败'
        })
    }
    // 登录成功
    // 登陆成功后，调用jwt.sign()方法生成字符串，并通过token属性发送给客户端
    // 参数1：用户信息对象
    // 参数2：加密密钥
    // 参数3：配置对象，可以配置当前token的有效期
    const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, { expiresIn: '30s' })
    res.send({
        status: 200,
        message: '登录成功',
        token: tokenStr //要发送给客户端的token字符串
    })
})

// 这是有权限的接口
app.get('/admin/getinfo', function(req, res) {
    // 用req.user获取用户信息，并使用data属性将用户信息发送给客户
    console.log(req.user);

    res.send({
        status: 200,
        message: '获取用户信息成功',
        data: req.user //发送给客户端的用户信息
    })

})

// 使用全局错误处理中间件，捕获解析JWT失败后产生错误
app.use((err, req, res, next) => {
    // 这次错误是由token解析失败导致的
    if (err.name === 'UnauthorizedError') {
        return res.send({
            starus: 401,
            message: '无效的token'
        })
    }
    res.send({
        status: 500,
        message: '未知错误'
    })
})

// 调用app.listen方法，指定端口号启动web服务器
app.listen(8888, function() {
    console.log('Express server running at http://127.0.0.1');
})